#include "includes.h"
#include "string.h"
#include "stdarg.h"
#include "debug.h"

void usart_putchar(unsigned char ch)
{
    while (USART_GetFlagStatus(USART1, USART_FLAG_TC) == RESET);
    /* Place your implementation of fputc here */
    /* e.g. write a character to the USART */
    USART_SendData(USART1, (uint8_t) ch);
    /* Loop until the end of transmission */
    while (USART_GetFlagStatus(USART1, USART_FLAG_TC) == RESET)
    {
    }
}
unsigned char usart_getchar(void)
{
    unsigned char data;
    while (USART_GetFlagStatus(USART1,USART_FLAG_RXNE)== RESET){
        ;/*wait for RX register not empty*/
    }
    
	data = USART_ReceiveData(USART1);
    return data;
}

void sys_out_char(char c)
{
    usart_putchar(c);
}
void sys_itoa(int value, char *string, unsigned char radix)
{
    int i;
    int count = 0;
    unsigned long temp;
    unsigned long res;
    char ch[20];
    if(radix==10 && value<0){ch[0] = '-';count++;temp = 0-value;}
    else{temp = value;}
    while(1)
    {
        res = temp%radix;
        temp=temp/radix;
        if(res<10) ch[count++]=res+'0';
        else ch[count++]=res-10+'a';
        if(temp==0)
            break;
    }
    ch[count]='\0';
    string[0]='\0';
    for(i=0;i<count;i++)
        string[count-i-1]=ch[i];

    string[count]='\0';
}

char sys_in_byte(void)
{
    return (char) usart_getchar();
}

void sys_console_out(const char *buf, unsigned int nbytes)
{
    while (nbytes--)
    {
        sys_out_char(*buf++);
    }
}

void sys_printf (const char *p_str,...)
{
    int data;
    char* string_buf;
    va_list marker;
    char buf[20];
    
    va_start(marker,p_str);

    while(*p_str){
        if(*p_str == '%'){
            switch(*(++p_str))
            {
                case 'd':
                case 'D':
                    data = va_arg(marker,int);
                    sys_itoa(data,buf,10);
                    sys_console_out(buf,strlen(buf));
                    break;
                case 'x':
                case 'X':
                    data = va_arg(marker,unsigned int);
                    sys_itoa(data,buf,16);
                    sys_console_out(buf,strlen(buf));
                    break;
                case 's':
                    string_buf = va_arg(marker,char*);
                    sys_console_out(string_buf,strlen(string_buf));
                    break;
                case 'c':
                    data = va_arg(marker,int);
                    sys_out_char((char)data);
                    break;

                default:
                    data = va_arg(marker,int);
                    sys_itoa(data,buf,16);
                    sys_console_out(buf,strlen(buf));
                    break;
            }
        }else{
            if(*p_str == '\n')
                sys_out_char('\r');
            sys_out_char(*p_str);
        }
        p_str++;
    }
    va_end(marker);
    
    return ;
}
